package client

import (
	"errors"
	"learning/gooop/etcd/raft/config"
	"learning/gooop/etcd/raft/rpc"
)

type tRaftClientService struct {
	cfg     config.IRaftConfig
	clients map[string]IRaftClient
}

func NewRaftClientService(cfg config.IRaftConfig) IRaftClientService {
	it := new(tRaftClientService)
	it.init(cfg)
	return it
}

func (me *tRaftClientService) init(cfg config.IRaftConfig) {
	me.cfg = cfg
	me.clients = make(map[string]IRaftClient)

	for _, nc := range me.cfg.GetNodes() {
		me.clients[nc.GetID()] = me.createRaftClient(nc)
	}
}

func (me *tRaftClientService) createRaftClient(nodeCfg config.IRaftNodeConfig) IRaftClient {
	return newRaftClient(me.cfg, nodeCfg, nil)
}

func (me *tRaftClientService) UsingRaft(peerID string, action func(client rpc.IRaftRPC) error) error {
	it, ok := me.clients[peerID]
	if ok {
		return action(it)
	} else {
		return gErrorUnknownRaftPeer
	}
}

func (me *tRaftClientService) UsingKV(peerID string, action func(client rpc.IKVStoreRPC) error) error {
	it, ok := me.clients[peerID]
	if ok {
		return action(it)
	} else {
		return gErrorUnknownRaftPeer
	}
}

var gErrorUnknownRaftPeer = errors.New("unknown raft peer")
